package com.zjsos.db.hibernate;


import org.apache.commons.lang3.StringUtils;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
/**
 * 
 * 实现：java实体类成员变量[zId]转换到数据库是[z_id]
 * 我发现这里hibernate留了一个坑，hibernate5以后策略的数据结构做了调整：
 * 5以前是NamingStrategy
 * 5之后拆分成两个ImplicitNamingStrategy、PhysicalNamingStrategy
 * 所以按照以前的配置方案是不行的，考虑到之后数据中心的需求会走定制化，我这里继承PhysicalNamingStrategy做了自定义。
 * 之前在yml上没试成功，后来改成xml形式。
 * @author shar
 * @date 2018年5月18日16:20:53
 * https://blog.csdn.net/lmy86263/article/details/69053376
 */
public class MyPhysicalNamingStrategy implements PhysicalNamingStrategy {

	@Override
	public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnv) {
		return convert(identifier);
	}

	@Override
	public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnv) {
		return convert(identifier);
	}

	@Override
	public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnv) {
		return convert(identifier);
	}

	@Override
	public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnv) {
		return convert(identifier);
	}

	@Override
	public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnv) {
		/**
		 * 去年做的表都是c_shipinfo
		 * 按照这个策略，出来的结果是CShipinfo =>> cshipinfo
		 * 所以应该特殊处理下这种情况
		 */
		if (identifier == null || StringUtils.isBlank(identifier.getText())) {
			return identifier;
		}
		String identifierText = identifier.getText();
		if (identifierText.length()>2) {
			if(Character.isUpperCase(identifierText.charAt(0)) && Character.isUpperCase(identifierText.charAt(1))){
				String C_Shipinfo = identifierText.charAt(0) + "_" + identifierText.substring(1);
				return convert(Identifier.toIdentifier(C_Shipinfo));
			}
		}
		return convert(identifier);
	}

	private static Identifier convert(Identifier identifier) {
		if (identifier == null || StringUtils.isBlank(identifier.getText())) {
			return identifier;
		}

		String regex = "([a-z])([A-Z])";
		String replacement = "$1_$2";
		String newName = identifier.getText().replaceAll(regex, replacement).toLowerCase();
		return Identifier.toIdentifier(newName);
	}
	
	public static void main(String[] args) {
		
		String identifierText = "CShipinfo";
		String C_Shipinfo = identifierText.charAt(0) + "_" + identifierText.substring(1);
		System.out.println(C_Shipinfo);
		System.out.println(convert(Identifier.toIdentifier(C_Shipinfo)));
		System.out.println(1);
	}
}